#pragma once
using namespace std;

//stack, priority_queue �� ��������
template<typename Container> 
inline void print_adapter(Container cont)
{
	while (!cont.empty())
	{
		std::cout << cont.top() << " ";
		cont.pop();
	}
	std::cout << std::endl;
}

//queue<T> �� ��������
template<typename T>
inline void print_adapter(std::queue<T> cont)
{
	while (!cont.empty())
	{
		std::cout << cont.front() << " ";
		cont.pop();
	}
	std::cout << std::endl;
}

//queue<T*> �� ��������
template<typename T>
inline void print_adapter(std::queue<T*> cont)
{
	while (!cont.empty())
	{
		std::cout << *cont.front() << " ";
		cont.pop();
	}
	std::cout << std::endl;
}

//vector
template<typename T>
inline void print_container(const std::vector<T>& cont)
{
	for (size_t i = 0; i < cont.size(); i++)
	{
		std::cout << cont[i] << " ";
	}
	std::cout << std::endl;
}

//
template<typename Container>
inline void print_container(const Container& cont)
{
	typename Container::const_iterator it_b = cont.begin(), it_end = cont.end();

	while (it_b!= it_end)
	{
		std::cout << *it_b << " ";
		++it_b;
	}
	std::cout << std::endl;
}

template<typename Container>
inline void print_associative_container(const Container& cont)
{
	typename Container::const_iterator it_b = cont.begin(), it_end = cont.end();

	while (it_b != it_end)
	{
		std::cout << (*it_b).first << ":"<< (*it_b).second<<" ";
		std::cout << std::endl;
		++it_b;
	}
	std::cout << std::endl;
}

template<>
inline void print_associative_container<std::map<const wchar_t*, int>>(const std::map<const wchar_t*, int>& cont)
{
	typename std::map<const wchar_t*, int>::const_iterator it_b = cont.begin(), it_end = cont.end();

	
	while (it_b != it_end)
	{
		std::wcout << (*it_b).first << ":" << (*it_b).second << std::endl;
		++it_b;
	}
	cout << endl;
}

template<>
inline void print_associative_container<std::map<char, std::set<string>>>(const std::map<char, std::set<string>>& cont)
{
	typename std::map<const char, std::set<string>>::const_iterator it_b = cont.begin(), it_end = cont.end();
	
	while (it_b != it_end)
	{
		std::cout << "\'"<<(*it_b).first << "\' - ";

		typename set<string>::const_iterator Cit_b = (*it_b).second.begin(), Cit_end = (*it_b).second.end();
		while (Cit_b != Cit_end)
		{
			std::cout << "\"" << *Cit_b << "\" ";
			++Cit_b;
		}
		std::cout << std::endl;
		++it_b;
	}
	cout << endl;
}

template<>
inline void print_associative_container<map<string, multiset<string>>>(const std::map<string, multiset<string>>& cont)
{
	typename map<string, multiset<string>>::const_iterator it_b = cont.begin(), it_end = cont.end();

	while (it_b != it_end)
	{
		std::cout << (*it_b).first << " : ";

		typename multiset<string>::const_iterator Cit_b = (*it_b).second.begin(), Cit_end = (*it_b).second.end();
		while (Cit_b != Cit_end)
		{
			std::cout << *Cit_b << " ";
			++Cit_b;
		}
		std::cout << std::endl;
		++it_b;
	}
	cout << endl;
}


//���������������� ���������� ��� const char*
class comp
{
public:
	bool operator()(const char* lhs, const char* rhs) const
	{
		// < 0, ���� str1 < str2
		//	= 0, ���� str1 = str2
		//>0, ���� str1 > str2

		if (strcmp(lhs, rhs) <= 0) return false;
		return true;
	}
};